// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of the
// License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "flare/base/logging.h"

#include "benchmark/benchmark.h"

// The benchmark result makes little sense, as L1i / iTLB effect is negligible
// for such small method, and branch predictor should always predict right.
//
// However, when needed, it helps us to compare code generated by FLARE_XXX and
// glog. So I keep it here.

// Run on (76 X 2494.14 MHz CPU s)
// CPU Caches:
//   L1 Data 32K (x76)
//   L1 Instruction 32K (x76)
//   L2 Unified 4096K (x76)
// Load Average: 0.31, 0.44, 0.42
// -----------------------------------------------------------------
// Benchmark                       Time             CPU   Iterations
// -----------------------------------------------------------------
// Benchmark_FlareCheck         1.99 ns         1.99 ns    352364237
// Benchmark_Check              1.99 ns         1.99 ns    352323842
// Benchmark_FlareCheckOp       1.64 ns         1.64 ns    427897862
// Benchmark_CheckOp            1.60 ns         1.60 ns    438266981

namespace flare {

volatile int x, y;

void Benchmark_FlareCheck(benchmark::State& state) {
  while (state.KeepRunning()) {
    FLARE_CHECK(!x);
    FLARE_CHECK(!x, "Some sophisticated log [{}].", x);
  }
}

BENCHMARK(Benchmark_FlareCheck);

void Benchmark_Check(benchmark::State& state) {
  while (state.KeepRunning()) {
    CHECK(!x);
    CHECK(!x) << "Some sophisticated log [" << x << "].";
  }
}

BENCHMARK(Benchmark_Check);

void Benchmark_FlareCheckOp(benchmark::State& state) {
  while (state.KeepRunning()) {
    FLARE_CHECK_LE(x, y);
    FLARE_CHECK_LE(x, y, "Some sophisticated log [{}, {}].", x, y);
  }
}

BENCHMARK(Benchmark_FlareCheckOp);

void Benchmark_CheckOp(benchmark::State& state) {
  while (state.KeepRunning()) {
    CHECK_LE(x, y);
    CHECK_LE(x, y) << "Some sophisticated log [" << x << ", " << y << "].";
  }
}

BENCHMARK(Benchmark_CheckOp);

}  // namespace flare
